// _Test7_SlideShowEffect.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include <iostream>
#include "Ct.h"
#include "string.h"
#include <fstream>

#define TRANSFORM_WIDTH_STEP 10
#define TRANSFORM_HEIGHT_STEP 10

using namespace std;


void SlideHozUp(IplImage *, IplImage *);
void SlideHozDown(IplImage *, IplImage *);
void CombHoz(IplImage *, IplImage *);
void CombVer(IplImage *, IplImage *);


bool fileExists(char * fileName)
{
	ifstream iFile;
	iFile.open(fileName);
	bool i = iFile.is_open();
	iFile.close();
	return i;
}

int main(int argc, char * argv[])
{
	if(argc==1)
	{
		cout << "Use: " << argv[0] << " image1 image2 animation\n";
		cout << "\tAnimation:\n";
		cout << "\t\tSlideHozUp\n";
		cout << "\t\tSlideHozDown\n";
		cout << "\t\tCombHoz\n";
		cout << "\t\tCombVer\n";
		return 0;

	}
	if(!fileExists(argv[1]))
	{
		cout << "File " << argv[1] << " not found";
		return 0;
	}
	else if (!fileExists(argv[2]))
	{
		cout << "File " << argv[2] << " not found";
		return 0;
	}
	cvNamedWindow("Result",CV_WINDOW_AUTOSIZE);
	IplImage * image = cvLoadImage(argv[1],1);
	IplImage * image2 = cvLoadImage(argv[2], 1);
	if(!strcmp(argv[3],"SlideHozUp"))
	{
		SlideHozUp(image, image2);
	}
	else if (!strcmp(argv[3],"SlideHozDown"))
	{
		SlideHozDown(image, image2);
	}
	else if (!strcmp(argv[3],"CombHoz"))
	{
		CombHoz(image, image2);
	}
	else if (!strcmp(argv[3],"CombVer"))
	{
		CombVer(image, image2);
	}
}


void SlideHozUp(IplImage * img, IplImage * img2)
{
	char * p1, *p2;
	IplImage * result= cvCreateImage(cvSize(img->width, img->height), img->depth, img->nChannels);
	cvCopy(img, result);
	cvNamedWindow("Result", CV_WINDOW_AUTOSIZE);
	while(1)
	{
		for(int i = img->height-1; i >= 0; i--)
		{
			for(int j = 0; j < img->width; j++)
			{
				int index = i * (img->widthStep) + j * img->nChannels;
				p1 = & (result->imageData[index]);
				p2 = & (img2->imageData[index]);
				p1[0] = p2[0];
				p1[1] = p2[1];
				p1[2] = p2[2];
			}
			if(i % TRANSFORM_HEIGHT_STEP)
			{
				cvShowImage("Result", result);
				cvWaitKey(1);
			}
		}
		break;
	}
	cvWaitKey(0);
	cvDestroyWindow("Result");
	cvReleaseImage(&result);
}
void SlideHozDown(IplImage * img, IplImage * img2)
{
	char * p1, *p2;
	IplImage * result= cvCreateImage(cvSize(img->width, img->height), img->depth, img->nChannels);
	cvCopy(img, result);
	cvNamedWindow("Result", CV_WINDOW_AUTOSIZE);
	while(1)
	{
		for(int i = 0; i <= img->height; i++)
		{
			for(int j = 0; j < img->width; j++)
			{
				int index = i * (img->widthStep) + j * img->nChannels;
				p1 = & (result->imageData[index]);
				p2 = & (img2->imageData[index]);
				p1[0] = p2[0];
				p1[1] = p2[1];
				p1[2] = p2[2];
			}
			if(i % TRANSFORM_HEIGHT_STEP)
			{
				cvShowImage("Result", result);
				cvWaitKey(1);
			}
		}
		break;
	}
	cvWaitKey(0);
	cvDestroyWindow("Result");
	cvReleaseImage(&result);
}

void CombHoz(IplImage * img, IplImage * img2)
{
	char * p1, *p2;
	IplImage * result= cvCreateImage(cvSize(img->width, img->height), img->depth, img->nChannels);
	cvCopy(img, result);
	cvNamedWindow("Result", CV_WINDOW_AUTOSIZE);
	int length = 0, i, type = 0;
	while(1)
	{
		length += TRANSFORM_WIDTH_STEP; // thay doi do dai
		type = -1;
		for(i = 0; i < img->height; i+= TRANSFORM_HEIGHT_STEP)
		{
			type++;
			//cac' dong` se ba't da`u
			int miniWidth = min(length, img->width); // lay can. do. da`i
			int bound = min(i+TRANSFORM_HEIGHT_STEP, img->height); // lay can tren
			for(int j = i; j < bound ; j++) //quet' la`n luot cac do`ng trong tu`ng block
			{
				//truong hop block chan/le
				if(type%2)
				{
					//chan~ -> lay hi`nh tu ben trai' qua phai
					for(int k = 0; k < miniWidth; k++)
					{
						int index1 = j * img->widthStep + k * img->nChannels; //index cua hi`nh des (lay ben trai)
						int index2 = j * img->widthStep + (img->width - k - 1) * img->nChannels; //index cua ne`n,lay ben phai
						//lay dia chi cua 2 hinh
						p2 = & img2->imageData[index1];
						p1 = & result->imageData[index2];
						p1[0] = p2[0];
						p1[1] = p2[1];
						p1[2] = p2[2];
					}
				}
				else
				{
					//le -> lay tu ben phai qua trai
					for(int k = 0; k < miniWidth; k++)
					{
						int index1 = j * img->widthStep + k * img->nChannels; //index cua hi`nh des (lay ben trai)
						int index2 = j * img->widthStep + (img->width - k - 1) * img->nChannels; //index cua ne`n,lay ben phai
						p2 = & img2->imageData[index2];
						p1 = & result->imageData[index1];
						p1[0] = p2[0];
						p1[1] = p2[1];
						p1[2] = p2[2];
					}
				}
			}
		}
		cvShowImage("Result", result);		
		cvWaitKey(1);
		if(length >= img->width)
			break;
	}
	cvWaitKey(0);
	cvDestroyWindow("Result");
	cvReleaseImage(&result);
}

void CombVer(IplImage * img, IplImage * img2)
{
	char * p1, *p2;
	IplImage * result= cvCreateImage(cvSize(img->width, img->height), img->depth, img->nChannels);
	cvCopy(img, result);
	cvNamedWindow("Result", CV_WINDOW_AUTOSIZE);
	int length = 0, i, type = 0;
	while(1)
	{
		length += TRANSFORM_HEIGHT_STEP; // thay doi do dai
		type = -1;
		for(i = 0; i < img->width; i+= TRANSFORM_WIDTH_STEP)
		{
			type++;
			//cac' dong` se ba't da`u
			int miniHeight = min(length, img->height); // lay can. chieu cao
			int bound = min(i+TRANSFORM_WIDTH_STEP, img->width); // lay can tren do dai
			for(int j = 0; j < miniHeight ; j++)
			{
				if(type%2)
				{
					for(int k = i; k < bound; k++)
					{
						int index1 = j * img->widthStep + k * img->nChannels; //index cua hi`nh des (lay ben trai)
						int index2 = (img->height-j-1) * img->widthStep + k * img->nChannels; //index cua ne`n,lay ben phai
						//lay dia chi cua 2 hinh
						p2 = & img2->imageData[index1];
						p1 = & result->imageData[index2];
						p1[0] = p2[0];
						p1[1] = p2[1];
						p1[2] = p2[2];
					}
				}
				else
				{
					for(int k = i; k < bound; k++)
					{int index1 = j * img->widthStep + k * img->nChannels; //index cua hi`nh des (lay ben trai)
					int index2 = (img->height-j-1) * img->widthStep + k * img->nChannels; //index cua ne`n,lay ben phai
					//lay dia chi cua 2 hinh
					p2 = & img2->imageData[index2];
					p1 = & result->imageData[index1];
					p1[0] = p2[0];
					p1[1] = p2[1];
					p1[2] = p2[2];
					}
				}
			}
		}
		cvShowImage("Result", result);		
		cvWaitKey(1);
		if(length >= img->height)
			break;
	}
	cvWaitKey(0);
	cvDestroyWindow("Result");
	cvReleaseImage(&result);
}